# encoding: utf-8
# @File  : results.py
# @Author: shaoyun
# @Date  :  2025/05/11
from typing import Dict, Any

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session

from app.api.dependencies import get_current_user, get_db
from app.core.response import get_response
from app.core.status_codes import SUCCESS, ERROR, TASK_NOT_FOUND
from app.models.spider_result import SpiderResult
from app.models.user import User
from app.services.results_manager import results_manager
from app.services.task_scheduler import TaskScheduler

router = APIRouter()


@router.get("/{task_id}", response_model=Dict[str, Any])
async def get_task_result(
        task_id: str,
        db: Session = Depends(get_db),
        current_user: User = Depends(get_current_user)
):
    """获取任务执行结果"""
    try:
        # 检查任务是否存在和权限
        task = await TaskScheduler.get_task(db, task_id)
        if not task:
            return get_response(TASK_NOT_FOUND, data=None)

        # 检查权限
        if current_user.role.value != "admin" and task.user_id != current_user.id:
            raise HTTPException(status_code=403, detail="Permission denied")

        # 获取结果
        result = await results_manager.get_result(task_id)
        if not result:
            return get_response(SUCCESS, data={
                "task_id": task_id,
                "message": "No results found yet"
            })

        return get_response(SUCCESS, data=result.model_dump())
    except Exception as e:
        return get_response(ERROR, data={"error": str(e)})


@router.get("/spider/{spider_id}", response_model=Dict[str, Any])
async def get_spider_results(
        spider_id: str,
        skip: int = Query(0, ge=0),
        limit: int = Query(10, ge=1, le=100),
        db: Session = Depends(get_db),
        current_user: User = Depends(get_current_user)
):
    """获取指定爬虫的所有结果"""
    try:
        # 检查爬虫权限
        from app.db.mongo_manager import MongoDB
        spider = await MongoDB.find_one("spiders", {"_id": spider_id})
        if not spider:
            raise HTTPException(status_code=404, detail="Spider not found")

        # 检查权限
        if current_user.role.value != "admin" and spider.get("user_id") != current_user.id:
            raise HTTPException(status_code=403, detail="Permission denied")

        # 获取结果
        results = await results_manager.get_results_by_spider(spider_id, limit, skip)

        return get_response(SUCCESS, data={
            "spider_id": spider_id,
            "results": [r.model_dump() for r in results],
            "count": len(results),
            "skip": skip,
            "limit": limit
        })
    except HTTPException:
        raise
    except Exception as e:
        return get_response(ERROR, data={"error": str(e)})


@router.get("/latest/all", response_model=Dict[str, Any])
async def get_latest_results(
        limit: int = Query(10, ge=1, le=50),
        current_user: User = Depends(get_current_user)
):
    """获取最新的爬虫结果（管理员可查看所有，普通用户只能看自己的）"""
    try:
        if current_user.role.value == "admin":
            # 管理员可以看所有结果
            results = await results_manager.get_latest_results(limit)
        else:
            # 普通用户只能看自己的结果
            # 需要先获取用户的所有任务ID
            from app.db.mongo_manager import MongoDB
            user_tasks = await MongoDB.find_many(
                "tasks",
                {"user_id": current_user.id},
                limit=100
            )
            task_ids = [task["_id"] for task in user_tasks]

            # 获取这些任务的结果
            db = await MongoDB.get_database()
            cursor = db["spider_results"].find({
                "task_id": {"$in": task_ids}
            }).sort("created_at", -1).limit(limit)

            results = []
            async for doc in cursor:
                if "_id" in doc:
                    del doc["_id"]
                results.append(SpiderResult(**doc))

        return get_response(SUCCESS, data={
            "results": [r.model_dump() for r in results],
            "count": len(results)
        })
    except Exception as e:
        return get_response(ERROR, data={"error": str(e)})


@router.get("/stats/{spider_id}", response_model=Dict[str, Any])
async def get_spider_result_stats(
        spider_id: str,
        db: Session = Depends(get_db),
        current_user: User = Depends(get_current_user)
):
    """获取爬虫结果统计信息"""
    try:
        # 检查爬虫权限
        from app.db.mongo_manager import MongoDB
        spider = await MongoDB.find_one("spiders", {"_id": spider_id})
        if not spider:
            raise HTTPException(status_code=404, detail="Spider not found")

        # 检查权限
        if current_user.role.value != "admin" and spider.get("user_id") != current_user.id:
            raise HTTPException(status_code=403, detail="Permission denied")

        # 获取统计信息
        stats = await results_manager.get_results_stats(spider_id)

        return get_response(SUCCESS, data={
            "spider_id": spider_id,
            "stats": stats
        })
    except HTTPException:
        raise
    except Exception as e:
        return get_response(ERROR, data={"error": str(e)})


@router.delete("/{task_id}", response_model=Dict[str, Any])
async def delete_task_result(
        task_id: str,
        db: Session = Depends(get_db),
        current_user: User = Depends(get_current_user)
):
    """删除任务结果（仅管理员）"""
    try:
        # 只有管理员可以删除结果
        if current_user.role.value != "admin":
            raise HTTPException(status_code=403, detail="Only admin can delete results")

        # 删除结果
        success = await results_manager.delete_result(task_id)

        if success:
            return get_response(SUCCESS, data={"message": "Result deleted successfully"})
        else:
            return get_response(ERROR, data={"message": "Result not found or already deleted"})
    except HTTPException:
        raise
    except Exception as e:
        return get_response(ERROR, data={"error": str(e)})


@router.post("/cleanup", response_model=Dict[str, Any])
async def cleanup_old_results(
        days: int = Query(30, ge=7, le=365, description="Delete results older than X days"),
        current_user: User = Depends(get_current_user)
):
    """清理旧的结果数据（仅管理员）"""
    try:
        # 只有管理员可以清理数据
        if current_user.role.value != "admin":
            raise HTTPException(status_code=403, detail="Only admin can cleanup results")

        # 执行清理
        deleted_count = await results_manager.cleanup_old_results(days)

        return get_response(SUCCESS, data={
            "message": f"Cleaned up {deleted_count} old results",
            "deleted_count": deleted_count,
            "older_than_days": days
        })
    except HTTPException:
        raise
    except Exception as e:
        return get_response(ERROR, data={"error": str(e)})